package 动态代理;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
/**
 * 模拟SpringAOP
 *
 * CGLIB 通过动态修改字节码生成目标代理对象
 * CGLIB底层使用ASM字节码操作库
 *
 * */
/** CGLIB 测试 */
public class CGLIBTest1 {
    public static void main(String[] args) {

        Cook masterCook = (Cook) Enhancer.create(Cook.class, new MasterCookProxy());
        masterCook.doing();
        masterCook.wash();

        System.out.println("============spring aop 代理指定方法 =============");
        Cook masterCook2 = (Cook) Enhancer.create(Cook.class, new SelfMaster());

        masterCook2.doing();
        masterCook2.wash();



    }
}


class MasterCookProxy implements MethodInterceptor {
    /**
     * 代理了所有方法
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("大师调味");
        Object result= methodProxy.invokeSuper(o, objects);
        System.out.println("精致摆盘");
        return result;
    }
}

class Cook {
    public  void doing(){
        System.out.println("做饭");
    }
    public  void wash(){
        System.out.println("洗碗");
    }
}


/** 模拟SpringAOP */
abstract class BaseAspect implements MethodInterceptor{

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = null;
        if(isIntercept(method,objects)){
            begin();
            try {
                before();
                result = methodProxy.invokeSuper(o, objects);
                after();
            }catch (Exception e){
                error(e);
            }finally {
                end();
            }
        }else {
            result = methodProxy.invokeSuper(o, objects);
        }
        return result;
    }

    /**
     * 切入点判断
     */
    public boolean isIntercept(Method method, Object[] args) throws Throwable {
        return true;
    }

    public void begin(){};
    public void before(){};
    public void after(){};
    public void error(Throwable e){};
    public void end(){};

}

class SelfMaster extends BaseAspect{
    /**
     * 切入点
     */
    public boolean isIntercept(Method method, Object[] args) throws Throwable {
        return method.getName().equals("doing");
    }

    @Override
    public void before() {
        System.out.println("大师调味");
    }

    @Override
    public void end() {
        System.out.println("精致摆盘");
    }
}
